<template>
  <div>
    <!--
      tree组件内,默认会使用数组里对象的 label 属性值,作为每行节点内容渲染
      但是我们 PermissionList 里对象 name 才是名字,所以 props 配合 label,
      告诉 tree 组件内,使用对象的 name 属性的值,作为每行节点渲染内容

      node-key: 设置每行唯一标识,(用的 data 里数组里对象的某个字段的值) 告诉 tree 用对象 id 的值
                作为每行的标识
      default-checked-keys: 设置默认选中的id(但是仅仅局限于数组里上来就有值的,如果后续赋值,不会影响默认选中)
      该组件一上来就默认创建,不显示而已,所以默认一开始为空数组,等点击分配按钮时才会向该数组传递 perIds 数组
     -->
    <el-tree
    ref="theTree"
    :data="permissionList"
    :props="{ label: 'name' }"
    default-expand-all
    show-checkbox
    check-strictly
    node-key="id"
    @check="nodeclickfn"
    ></el-tree>
    <el-row class="footer" type="flex" justify="center">
      <el-col :span="6">
        <el-button size="small" @click="cancelButton">取 消</el-button>
        <el-button size="small" type="primary" @click="setRolesBtn">确 定</el-button>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'AssignPermission',
  props: {
    permissionList: { // 嵌套children的展示数组
      type: Array,
      default: () => ([])
    },
    permIds: { // 角色已选择了的权限点,角色现有的权限点数(权限点id字符串中的值),该属性不会在页面上使用
      type: Array,
      default: () => ([])
    }
    // permissionList: {
    //   type: Array,
    //   default: _ => []
    // },
    // roleId: {
    //   type: [Number, String],
    //   required: true
    // }
  },
  watch: {
    permIds(){ // 利用函数完成默认选中功能,因为组件的 default-checked-keys 属性无法完成我的功能
    // default-checked-keys 只能是初次渲染时数组内有值才能渲染出来,但我们初次渲染时没值所以这个属性用不了,
      this.$refs.theTree.setCheckedKeys(this.permIds) // 只会在初次加载该页面时执行一次函数
    }
  },
  data() {
    return {
      resPermissionList:[] ,
    }
  },
  created() {
  },
  methods: {
    // 取消按钮
    cancelButton() {
      this.$emit('input',false)
    },
    // 点击任何节点时都会触发的事件
    nodeclickfn(data,list){
      /*
          开启 check-strictly 不相关联
          可能性
          点击父节点:
            1 父节点为 true ,无法进入if判断下的 for 循环,赋值 > 渲染
            2 父节点为 false ,进入 else 判断 如果没有子节点 ,赋值 > 渲染
            3 父节点为 false ,进入 else 判断 如果有孩子, 使用 getNode 组件方法获取到 CheckBox 本身
              this.$refs.theTree.getNode(data.id)
              循环 children 里面的孩子,进行 filter 过滤,keys数组为最终输出的渲染数组
              keys = keys.filter(key => key !== CurrentChildrenId), 渲染数组内过滤掉当前父节点下的该子节点
          点击子节点:
            else 判断无法进去,因为子节点没有 children
            1 子节点为 true,进入 if 判断,现在这里只执行一次for循环操作,通过 getNode(子节点) 方法
              找到当前子节点的父节点,然后把当前子节点的父节点的checked强制改为 false ,利用 setChecked 方法
              然后判断当前子节点的父节点checked是否为true,true则执行,
              往 keys 渲染数组内添加当前子节点的父节点的id
              bug : 但是如果该父节点下有2个子节点,每点击一个子节点就会添加一次父节点
              需要进行过滤掉多余的父节点操作
            2 子节点为 false,不进入 if else,因为上面已经获取过实时最新的渲染数组, 赋值 > 渲染
            let keys = this.$refs.theTree.getCheckedKeys() // 获取已勾选节点的key值,最后输出该数组为渲染内容
      */
      // data 当前 item项, list 当前已选择(全部)项
      let thisNode = this.$refs.theTree.getNode(data.id) // 获取当前选中节点
      let keys = this.$refs.theTree.getCheckedKeys() // 获取已勾选节点的key值,最后输出该数组为渲染内容
      if (thisNode.checked) { // 当前节点若被选中
       for (let i = thisNode.level; i > 1; i--) { // 1级节点不会进入判断,2级节点之后才会进入
         // 当前子节点选中，取消勾选父节点(就算已选择也强制改为未选择)
         this.$refs.theTree.setChecked(thisNode.parent, false)
         // 判断是否有父级节点
         if (!thisNode.parent.checked) { // 父级节点未被选中，则将父节点替换成当前节点，往上继续查询，并将此节点key存入keys数组
           keys.push(thisNode.parent.data.id)
           // 去重,例如该父节点下有2个子节点,每点击一个子节点就会添加一次父节点
           keys = keys.filter((item,index,arr) => arr.indexOf(item) == index)
         }
       }
     }else{ // 选中状态为 false && 有孩子时(只有一级父节点才会进入这里,二级没有孩子进不来)
       if(!thisNode.checked && !!thisNode.childNodes.length){
         // 当点击节点时,选中状态为 false,就要不管三七二十一,把该节点下的所有孩子都过滤掉
         thisNode.childNodes.forEach(children => { // 循环当前父节点内的孩子
         // 过滤当前父节点内的所有孩子
           keys = keys.filter(id => id !== children.data.id)
         })
       }
     }
     this.$refs.theTree.setCheckedKeys(keys) // 将所有keys数组的节点全选中
     this.resPermissionList = keys
    },
    // 设置权限按钮
    setRolesBtn() {
      // 保存当前角色已选择的权限点数据
      // this.$refs.theTree.getCheckedKeys() 得到的是,已选择权限点(id值)组成的数组
      // 例子: ['604f7df5f900be1850edb152', '6050175b140b332e04cced02',]
      this.$emit('saveRolePer',this.resPermissionList)
      this.$emit('input',false)
    }
  }
}
</script>

<style lang="scss" scoped>
.footer {
  margin-top: 30px;
}
</style>
